package com.wfh.mianshiji.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wfh.mianshiji.ai.agent.InterviewAgent;
import com.wfh.mianshiji.common.ErrorCode;
import com.wfh.mianshiji.exception.BusinessException;
import com.wfh.mianshiji.model.dto.MqMessageDto;
import com.wfh.mianshiji.model.dto.interview.InterviewCreateRequest;
import com.wfh.mianshiji.model.dto.interview.InterviewStopRequest;
import com.wfh.mianshiji.model.entity.Interview;
import com.wfh.mianshiji.model.enums.InterviewStatusEnum;
import com.wfh.mianshiji.model.vo.InterviewVo;
import com.wfh.mianshiji.mq.Producer;
import com.wfh.mianshiji.service.InterviewService;
import com.wfh.mianshiji.mapper.InterviewMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
* @author fenghuanwang
* @description 针对表【interview(面试表)】的数据库操作Service实现
* @createDate 2025-10-30 15:36:18
*/
@Service
public class InterviewServiceImpl extends ServiceImpl<InterviewMapper, Interview>
    implements InterviewService{

    @Resource
    private InterviewAgent interviewAgent;

    @Resource
    private Producer producer;


    /**
     * 结束词集合
     */
    private static final Set<String> TERMINATION_KEYWORDS = Set.of("结束", "停止", "完成");

    private boolean messageContainsTerminationKeyword(String message) {
        return TERMINATION_KEYWORDS.stream().anyMatch(message::contains);
    }

    /**
     * 开始面试
     *
     * @param userId      用户ID
     * @param interviewId 面试ID
     * @param message     用户的输入
     * @param request
     * @return
     */
    @Override
    public Flux<String> start(Long userId, Long interviewId, String message, HttpServletRequest request) {
        if (StringUtils.isBlank(message)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "消息内容不能为空");
        }

        List<Interview> interviewList = this.getBaseMapper().selectList(
                new QueryWrapper<Interview>()
                        .eq("id", interviewId)
                        .eq("userId", userId)
        );
        if (interviewList.isEmpty()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "面试场次不存在");
        }

        Interview interview = interviewList.getFirst();
        Integer currentStatus = interview.getInterviewStatus();

        // 如果已结束，直接拒绝
        if (InterviewStatusEnum.FINISHED.getValue().equals(currentStatus)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "面试已结束，无法继续操作");
        }

        String resumeContent = interview.getResumeContent();
        String jobDescription = interview.getJobDescription();
        String jobTitle = interview.getJobTitle();

        if (InterviewStatusEnum.NOT.getValue().equals(currentStatus)) {
            // 首次开始
            interview.setInterviewStatus(InterviewStatusEnum.DOING.getValue());
            this.updateById(interview);
            String prompt = String.format("这是该用户的简历:%s, 以及求职岗位名称:%s, 求职岗位职责:%s,请根据这些内容为用户进行面试()",
                    resumeContent, jobTitle, jobDescription);
            return interviewAgent.doChatStream(prompt, String.valueOf(interviewId));
        }

        // 如果正在用户的对话中提出要结束的话，也要设置状态并发送到消息队列分析结果
        if (messageContainsTerminationKeyword(message)) {
            interview.setInterviewStatus(InterviewStatusEnum.FINISHED.getValue());
            interview.setStopTime(new Date());
            this.updateById(interview);
            // 发送到消息队列
            MqMessageDto mqMessageDto = new MqMessageDto();
            mqMessageDto.setUserId(userId);
            mqMessageDto.setInterviewId(interviewId);
            producer.sendMsg(mqMessageDto);
            return interviewAgent.doChatStream(message, String.valueOf(interviewId));
        }

        // 正常对话（DOING 状态）
        if (InterviewStatusEnum.DOING.getValue().equals(currentStatus)) {
            return interviewAgent.doChatStream(message, String.valueOf(interviewId));
        }

        throw new BusinessException(ErrorCode.OPERATION_ERROR, "未知的面试状态");
    }

    /**
     * 创建面试
     *
     * @param interviewCreateRequest
     * @return
     */
    @Override
    public InterviewVo create(InterviewCreateRequest interviewCreateRequest) {
        Long userId = interviewCreateRequest.getUserId();
        String jobTitle = interviewCreateRequest.getJobTitle();
        String jobDesc = interviewCreateRequest.getJobDesc();
        List<String> resumeList = interviewCreateRequest.getResumeList();
        // 向数据库中插入一条面试场次数据
        Interview interview = new Interview();
        interview.setUserId(userId);
        interview.setJobTitle(jobTitle);
        interview.setJobDescription(jobDesc);
        interview.setResumeContent(resumeList.getFirst());
        interview.setInterviewStatus(InterviewStatusEnum.NOT.getValue());
        interview.setStartTime(new Date());
        interview.setInterviewTime(new Date());
        interview.setInterviewType(0);
        this.save(interview);
        return BeanUtil.copyProperties(interview, InterviewVo.class);
    }

    /**
     * 停止面试
     *
     * @param interviewStopRequest
     * @return
     */
    @Override
    public Boolean stop(InterviewStopRequest interviewStopRequest) {
        // 查询当前面试场次,更新当前面试场次状态
        Long userId = interviewStopRequest.getUserId();
        Long interviewId = interviewStopRequest.getInterviewId();
        String message = interviewStopRequest.getMessage();
        if (!message.equals(InterviewStatusEnum.FINISHED.getText())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "未知的面试状态");
        }
        Interview interview = this.getOne(new QueryWrapper<>(Interview.class).eq("userId", userId).eq("id", interviewId));
        // 防御性编程
        if (interview == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "面试场次不存在");
        }
        interview.setInterviewStatus(InterviewStatusEnum.FINISHED.getValue());
        interview.setStopTime(new Date());
        // 更新当前面试场次状态
        boolean res = this.updateById(interview);
        // 同步Redis对话记录到MySQL
        MqMessageDto mqMessageDto = new MqMessageDto();
        mqMessageDto.setUserId(userId);
        mqMessageDto.setInterviewId(interviewId);
        // 发送到消息队列进行面试分析
        producer.sendMsg(mqMessageDto);
        return res;
    }
}




